﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using WenSkin.Controls;

namespace WenSkin.Test
{
    public class WenPie : WenControl
    {


        public WenPie() : base()
        {
        }

        #region 私有属性

        private int value = 5;
        private int cutCount = 60;

        #endregion

        #region 公有属性

        [Category("Wen"), Description("显示图标"), DefaultValue(null)]
        public Image Image { get; set; }

        [Category("Wen"), Description("进度值"), DefaultValue(0)]
        public int Value { get => value; set { this.value = value; this.Invalidate(); this.Refresh(); } }

        [Category("Wen"), Description("获取或设置最大值（切割份数）"), DefaultValue(60)]
        public int CutCount { get => cutCount; set => cutCount = value; }
        #endregion
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics.SetGDIHigh();

            if (Image == null)
                return;

            if (Value > CutCount)
                return;

            //计算中点
            float w = Width / 2;
            float h = Height / 2;

            g.DrawImage(Image, new Rectangle(0, 0, Width, Height));

            Bitmap bitmap = WhiteAndBlack(new Bitmap(Image));
            Image image = ResizeImage(bitmap, Width, Height);
            Brush brush = new TextureBrush(image);

            //计算坐标点
            //先确定角度
            double angle = 360.00 / CutCount * Value;
            if (angle >= 360)
                return;

            PointF pointF = new PointF();

            List<PointF> pointFs = new List<PointF>();
            if (angle < 45)
            {
                double tanValue = Math.PI * angle / 180;
                pointF.X = Math.Abs((float)(Math.Atan(tanValue) * h));
                pointF.Y = h;

                //设置路径并绘制
                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(w, h));
                pointFs.Add(new PointF(w, -h));
                pointFs.Add(new PointF(-w, -h));
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 90)
            {
                double tanValue = Math.PI * (90 - angle) / 180;
                pointF.Y = Math.Abs((float)Math.Tan(tanValue) * w);
                pointF.X = w;
                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(w, -h));
                pointFs.Add(new PointF(-w, -h));
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 135)
            {
                double tanValue = Math.PI * (angle - 90) / 180;
                pointF.Y = -Math.Abs((float)Math.Tan(tanValue) * w);
                pointF.X = w;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(w, -h));
                pointFs.Add(new PointF(-w, -h));
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 180)
            {
                double tanValue = Math.PI * (180 - angle) / 180;
                pointF.X = Math.Abs((float)Math.Tan(tanValue) * h);
                pointF.Y = -h;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(-w, -h));
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 225)
            {
                double tanValue = Math.PI * (angle - 180) / 180;
                pointF.X = -Math.Abs((float)Math.Tan(tanValue) * h);
                pointF.Y = -h;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(-w, -h));
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 270)
            {
                double tanValue = Math.PI * (270 - angle) / 180;
                pointF.Y = -Math.Abs((float)Math.Tan(tanValue) * w);
                pointF.X = -w;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 315)
            {
                double tanValue = Math.PI * (angle - 270) / 180;
                pointF.Y = Math.Abs((float)Math.Tan(tanValue) * w);
                pointF.X = -w;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
                pointFs.Add(new PointF(-w, h));
            }
            else if (angle < 360)
            {
                double tanValue = Math.PI * (360 - angle) / 180;
                pointF.X = -Math.Abs((float)Math.Tan(tanValue) * h);
                pointF.Y = h;

                pointFs.Add(new PointF(0, h));
                pointFs.Add(new PointF(0, 0));
                pointFs.Add(pointF);
            }

            g.FillPolygon(brush, PointConvert(pointFs.ToArray(), this.Width, this.Height));
        }

        /// <summary>  
        ///  Resize图片   
        /// </summary>  
        /// <param name="bmp">原始Bitmap </param>  
        /// <param name="newW">新的宽度</param>  
        /// <param name="newH">新的高度</param>  
        /// <returns>处理以后的图片</returns>  
        public static Bitmap ResizeImage(Image bmp, int newW, int newH)
        {
            try
            {
                Bitmap b = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(b);
                // 插值算法的质量   
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return b;
            }
            catch
            {
                return null;
            }
        }

        //数学点转为真实点
        public PointF[] PointConvert(PointF[] pointFs, int width, int height)
        {
            List<PointF> pointFsout = new List<PointF>();
            foreach (var item in pointFs)
            {
                pointFsout.Add(new PointF(item.X + width / 2, height / 2 - item.Y));
            }
            return pointFsout.ToArray();
        }
        public Bitmap WhiteAndBlack(System.Drawing.Bitmap image)
        {
            //原来图片的长度
            int width = image.Width;
            //原来图片的高度            
            int height = image.Height;
            //改变色素
            //横坐标
            for (int x = 0; x < width; x++)
            {
                //纵坐标
                for (int y = 0; y < height; y++)
                {
                    //获得坐标(x,y)颜色
                    Color color = image.GetPixel(x, y);
                    //获得该颜色下的黑白色
                    int value = (color.R + color.G + color.B) / 3;
                    //设置颜色
                    image.SetPixel(x, y, Color.FromArgb(value, value, value));
                }
            }
            return image;
        }

        //改变大小
        public void SaveImage(string path, int width, int height)
        {
            Bitmap bitmap = new Bitmap(this.Width, this.Height);
            this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));
            bitmap = ResizeImage(bitmap, width, height);
            bitmap.Save(path);
        }
        //原始大小
        public void SaveImage(string path)
        {
            Bitmap bitmap = new Bitmap(this.Width, this.Height);
            this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));
            bitmap.Save(path);
        }
    }
}
